package cn.livenovel.thirddata.lottery;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

import cn.livenovel.thirddata.dao.LotteryDAO;

/**
 * 统计信息计算
 * 
 * @author shaohui
 * @date 2017-06-21 13:26:49
 */
@Service
public class LotteryStatisticsService {
    
    @Autowired
    private LotteryDAO lotteryDAO;
    
    private final Logger logger = LoggerFactory.getLogger(LotteryStatisticsService.class);

    /**
     * 
     * 计算每一期的统计信息
     *
     * @param issue
     * @param unionLottos
     * @return
     * 
     * @author shaohui
     * @date 2017-06-21 13:39:08
     */
    public UnionLottoStatisticPO[] statisticUnionLotto(final int issue, List<UnionLottoPO> unionLottos) {
        UnionLottoStatisticPO[] result = new UnionLottoStatisticPO[UnionLottoPO.BALL_NUM];
        for (int i = 0; i < UnionLottoPO.BALL_NUM; i++) {
            UnionLottoStatisticPO unionLottoStatisticPO = new UnionLottoStatisticPO();
            unionLottoStatisticPO.setIssue(issue);
            unionLottoStatisticPO.setBallNum(UnionLottoPO.BALLS[i]);
            result[i] = unionLottoStatisticPO;
        }
        List<UnionLottoPO> legalList = unionLottos.stream().filter(item -> item.getIssue() <= issue).collect(Collectors.toList());
        for (int index = 0; index < legalList.size(); index++) {
            UnionLottoPO item = legalList.get(index);
            int issueNum = index + 1;
            for (int i = 0; i < UnionLottoPO.BALL_NUM; i++) {
                String ball = UnionLottoPO.BALLS[i];
                UnionLottoStatisticPO unionLottoStatisticPO = result[i];
                if (i < 33) { // 红球
                    unionLottoStatisticPO.setTheoryNum(6 * issueNum / 33);
                } else { // 篮球
                    unionLottoStatisticPO.setTheoryNum(issueNum / 16);
                }
                boolean appear = false;
                try {
                    appear = Boolean.valueOf(BeanUtils.getProperty(item, ball));
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                }
                if (appear) { // 出现
                    unionLottoStatisticPO.setActualNum(unionLottoStatisticPO.getActualNum() + 1);
                    unionLottoStatisticPO.setCurrentLoss(0);
                } else { // 遗漏
                    unionLottoStatisticPO.setCurrentLoss(unionLottoStatisticPO.getCurrentLoss() + 1);
                }
                unionLottoStatisticPO.setMaxLoss(Math.max(unionLottoStatisticPO.getMaxLoss(), unionLottoStatisticPO.getCurrentLoss()));
                unionLottoStatisticPO.setAvgLoss(issueNum / (unionLottoStatisticPO.getActualNum() + 1));
                unionLottoStatisticPO.setDeltaNum(unionLottoStatisticPO.getTheoryNum() - unionLottoStatisticPO.getActualNum());
                unionLottoStatisticPO.setProbability(Double.valueOf(unionLottoStatisticPO.getActualNum()) / issueNum);
                if (unionLottoStatisticPO.getMaxLoss() != 0) {
                    unionLottoStatisticPO.setInterveneIndex(Double.valueOf(unionLottoStatisticPO.getCurrentLoss()) / unionLottoStatisticPO.getMaxLoss());
                } else {
                    unionLottoStatisticPO.setInterveneIndex(0);
                }
            }
        }
        
        return result;
    }
    
    public void statisticUnionLottos() {
        List<UnionLottoPO> unionLottos = lotteryDAO.queryAllUnionLottos();
        List<UnionLottoStatisticPO> statistics = new ArrayList<>();
        for (UnionLottoPO unionLotto : unionLottos) {
            logger.info("正在统计第{}期数据..." , unionLotto.getIssue());
            UnionLottoStatisticPO[] unionLottoStatisticPOs = statisticUnionLotto(unionLotto.getIssue(), unionLottos);
            statistics.addAll(Lists.newArrayList(unionLottoStatisticPOs));
            if (statistics.size() > 100) {
                lotteryDAO.insertUnionLottoStatistics(statistics);
                statistics.clear();
            }
        }
        if (!statistics.isEmpty()) {
            lotteryDAO.insertUnionLottoStatistics(statistics);
        }
    }
}
